#pragma once

#include "../result.hpp"
#include "../models/alertmodel.hpp"
#include "../models/medicinemodel.hpp"
#include "../views/alertview.hpp"

namespace pharmacy_server
{
    class AlertController
    {
    public:
        static AlertController& instance()
        {
            static AlertController inst;
            return inst;
        }

    private:
        AlertController()
            : medicinemodel(MedicineModel::instance())
        {}
        AlertController(const AlertController&) = delete;
        AlertController& operator=(const AlertController&) = delete;

    public:
        Result check_stock_alerts()
        {
            try
            {
                std::vector<int> alerts = alertmodel.check_stock_alerts();

                Json::Value root;
                for (int id : alerts)
                {
                    Medicine* medicine = medicinemodel.get_medicine(id);
                    root.append(medicine->to_json());
                }

                return alertview.check_stock_alerts(true, "stock alerts checked", json_util::serialize(root));
            }
            catch (const model_except& e)
            {
                return alertview.check_stock_alerts(false, e.what());
            }
        }

        Result check_expiry()
        {
            try
            {
                AlertModel::expiry_result_type expiry = alertmodel.check_expiry();
                Json::Value root;

                for (const auto& info : expiry.first)
                {
                    Json::Value json = medicinemodel.get_medicine(info.id)->to_json();
                    json["expired_date"] = info.expired_date;
                    json["purchase_date"] = info.purchase_date;
                    root["already_expired"].append(json);
                }

                for (const auto& info : expiry.second)
                {
                    Json::Value json = medicinemodel.get_medicine(info.id)->to_json();
                    json["expired_date"] = info.expired_date;
                    json["purchase_date"] = info.purchase_date;
                    root["soon_to_expire"].append(json);
                }

                return alertview.check_expiry(true, "expiry dates checked", json_util::serialize(root));
            }
            catch (const model_except& e)
            {
                return alertview.check_expiry(false, e.what());
            }
        }

    private:
        MedicineModel& medicinemodel;
        AlertModel alertmodel;
        AlertView alertview;
    };
}